home *** CD-ROM | disk | FTP | other *** search
/ Aminet 40 / Aminet 40 (2000)(Schatztruhe)[!][Dec 2000].iso / Aminet / dev / lang / Python16.lha / Python-1.6 / Lib / Python1.6 / audiodev.py < prev    next >
Encoding:
Python Source  |  2000-02-02  |  5.7 KB  |  254 lines

  1. """Classes for manipulating audio devices (currently only for Sun and SGI)"""
  2.  
  3. error = 'audiodev.error'
  4.  
  5. class Play_Audio_sgi:
  6.     # Private instance variables
  7. ##     if 0: access frameratelist, nchannelslist, sampwidthlist, oldparams, \
  8. ##           params, config, inited_outrate, inited_width, \
  9. ##           inited_nchannels, port, converter, classinited: private
  10.  
  11.     classinited = 0
  12.     frameratelist = nchannelslist = sampwidthlist = None
  13.  
  14.     def initclass(self):
  15.         import AL
  16.         self.frameratelist = [
  17.               (48000, AL.RATE_48000),
  18.               (44100, AL.RATE_44100),
  19.               (32000, AL.RATE_32000),
  20.               (22050, AL.RATE_22050),
  21.               (16000, AL.RATE_16000),
  22.               (11025, AL.RATE_11025),
  23.               ( 8000,  AL.RATE_8000),
  24.               ]
  25.         self.nchannelslist = [
  26.               (1, AL.MONO),
  27.               (2, AL.STEREO),
  28.               (4, AL.QUADRO),
  29.               ]
  30.         self.sampwidthlist = [
  31.               (1, AL.SAMPLE_8),
  32.               (2, AL.SAMPLE_16),
  33.               (3, AL.SAMPLE_24),
  34.               ]
  35.         self.classinited = 1
  36.  
  37.     def __init__(self):
  38.         import al, AL
  39.         if not self.classinited:
  40.             self.initclass()
  41.         self.oldparams = []
  42.         self.params = [AL.OUTPUT_RATE, 0]
  43.         self.config = al.newconfig()
  44.         self.inited_outrate = 0
  45.         self.inited_width = 0
  46.         self.inited_nchannels = 0
  47.         self.converter = None
  48.         self.port = None
  49.         return
  50.  
  51.     def __del__(self):
  52.         if self.port:
  53.             self.stop()
  54.         if self.oldparams:
  55.             import al, AL
  56.             al.setparams(AL.DEFAULT_DEVICE, self.oldparams)
  57.             self.oldparams = []
  58.  
  59.     def wait(self):
  60.         if not self.port:
  61.             return
  62.         import time
  63.         while self.port.getfilled() > 0:
  64.             time.sleep(0.1)
  65.         self.stop()
  66.  
  67.     def stop(self):
  68.         if self.port:
  69.             self.port.closeport()
  70.             self.port = None
  71.         if self.oldparams:
  72.             import al, AL
  73.             al.setparams(AL.DEFAULT_DEVICE, self.oldparams)
  74.             self.oldparams = []
  75.  
  76.     def setoutrate(self, rate):
  77.         for (raw, cooked) in self.frameratelist:
  78.             if rate == raw:
  79.                 self.params[1] = cooked
  80.                 self.inited_outrate = 1
  81.                 break
  82.         else:
  83.             raise error, 'bad output rate'
  84.  
  85.     def setsampwidth(self, width):
  86.         for (raw, cooked) in self.sampwidthlist:
  87.             if width == raw:
  88.                 self.config.setwidth(cooked)
  89.                 self.inited_width = 1
  90.                 break
  91.         else:
  92.             if width == 0:
  93.                 import AL
  94.                 self.inited_width = 0
  95.                 self.config.setwidth(AL.SAMPLE_16)
  96.                 self.converter = self.ulaw2lin
  97.             else:
  98.                 raise error, 'bad sample width'
  99.  
  100.     def setnchannels(self, nchannels):
  101.         for (raw, cooked) in self.nchannelslist:
  102.             if nchannels == raw:
  103.                 self.config.setchannels(cooked)
  104.                 self.inited_nchannels = 1
  105.                 break
  106.         else:
  107.             raise error, 'bad # of channels'
  108.  
  109.     def writeframes(self, data):
  110.         if not (self.inited_outrate and self.inited_nchannels):
  111.             raise error, 'params not specified'
  112.         if not self.port:
  113.             import al, AL
  114.             self.port = al.openport('Python', 'w', self.config)
  115.             self.oldparams = self.params[:]
  116.             al.getparams(AL.DEFAULT_DEVICE, self.oldparams)
  117.             al.setparams(AL.DEFAULT_DEVICE, self.params)
  118.         if self.converter:
  119.             data = self.converter(data)
  120.         self.port.writesamps(data)
  121.  
  122.     def getfilled(self):
  123.         if self.port:
  124.             return self.port.getfilled()
  125.         else:
  126.             return 0
  127.  
  128.     def getfillable(self):
  129.         if self.port:
  130.             return self.port.getfillable()
  131.         else:
  132.             return self.config.getqueuesize()
  133.  
  134.     # private methods
  135. ##     if 0: access *: private
  136.  
  137.     def ulaw2lin(self, data):
  138.         import audioop
  139.         return audioop.ulaw2lin(data, 2)
  140.  
  141. class Play_Audio_sun:
  142. ##     if 0: access outrate, sampwidth, nchannels, inited_outrate, inited_width, \
  143. ##           inited_nchannels, converter: private
  144.  
  145.     def __init__(self):
  146.         self.outrate = 0
  147.         self.sampwidth = 0
  148.         self.nchannels = 0
  149.         self.inited_outrate = 0
  150.         self.inited_width = 0
  151.         self.inited_nchannels = 0
  152.         self.converter = None
  153.         self.port = None
  154.         return
  155.  
  156.     def __del__(self):
  157.         self.stop()
  158.  
  159.     def setoutrate(self, rate):
  160.         self.outrate = rate
  161.         self.inited_outrate = 1
  162.  
  163.     def setsampwidth(self, width):
  164.         self.sampwidth = width
  165.         self.inited_width = 1
  166.  
  167.     def setnchannels(self, nchannels):
  168.         self.nchannels = nchannels
  169.         self.inited_nchannels = 1
  170.  
  171.     def writeframes(self, data):
  172.         if not (self.inited_outrate and self.inited_width and self.inited_nchannels):
  173.             raise error, 'params not specified'
  174.         if not self.port:
  175.             import sunaudiodev, SUNAUDIODEV
  176.             self.port = sunaudiodev.open('w')
  177.             info = self.port.getinfo()
  178.             info.o_sample_rate = self.outrate
  179.             info.o_channels = self.nchannels
  180.             if self.sampwidth == 0:
  181.                 info.o_precision = 8
  182.                 self.o_encoding = SUNAUDIODEV.ENCODING_ULAW
  183.                 # XXX Hack, hack -- leave defaults
  184.             else:
  185.                 info.o_precision = 8 * self.sampwidth
  186.                 info.o_encoding = SUNAUDIODEV.ENCODING_LINEAR
  187.                 self.port.setinfo(info)
  188.         if self.converter:
  189.             data = self.converter(data)
  190.         self.port.write(data)
  191.  
  192.     def wait(self):
  193.         if not self.port:
  194.             return
  195.         self.port.drain()
  196.         self.stop()
  197.  
  198.     def stop(self):
  199.         if self.port:
  200.             self.port.flush()
  201.             self.port.close()
  202.             self.port = None
  203.  
  204.     def getfilled(self):
  205.         if self.port:
  206.             return self.port.obufcount()
  207.         else:
  208.             return 0
  209.  
  210.     def getfillable(self):
  211.         return BUFFERSIZE - self.getfilled()
  212.  
  213. def AudioDev():
  214.     # Dynamically try to import and use a platform specific module.
  215.     try:
  216.         import al
  217.     except ImportError:
  218.         try:
  219.             import sunaudiodev
  220.             return Play_Audio_sun()
  221.         except ImportError:
  222.             try:
  223.                 import Audio_mac
  224.             except ImportError:
  225.                 raise error, 'no audio device'
  226.             else:
  227.                 return Audio_mac.Play_Audio_mac()
  228.     else:
  229.         return Play_Audio_sgi()
  230.  
  231. def test(fn = None):
  232.     import sys
  233.     if sys.argv[1:]:
  234.         fn = sys.argv[1]
  235.     else:
  236.         fn = 'f:just samples:just.aif'
  237.     import aifc
  238.     af = aifc.open(fn, 'r')
  239.     print fn, af.getparams()
  240.     p = AudioDev()
  241.     p.setoutrate(af.getframerate())
  242.     p.setsampwidth(af.getsampwidth())
  243.     p.setnchannels(af.getnchannels())
  244.     BUFSIZ = af.getframerate()/af.getsampwidth()/af.getnchannels()
  245.     while 1:
  246.         data = af.readframes(BUFSIZ)
  247.         if not data: break
  248.         print len(data)
  249.         p.writeframes(data)
  250.     p.wait()
  251.  
  252. if __name__ == '__main__':
  253.     test()
  254.